#![feature(ip_in_core)]

mod channel;
mod shared_state;
mod base;
mod io;
mod framing;
mod async_in_depth;
mod select;
mod echo_server;
mod client;

fn main() {
}

/*
#[cfg(test)]
mod test {
    trait EndPointHandler {
        fn connected(&self, e: &dyn std::error::Error);
        fn disconnected(&self, e: &dyn std::error::Error);
        fn buf_read(&self, buf: &mut dyn bytes::Buf);
    }

    struct EndPoint<R, W, H> {
        reader : R,
        writer: W,
        handle: Option<Box<dyn EndPointHandler>>,
    }

    impl<R, W, H> EndPoint<R, W, H> 
    where R: AsyncRead + std::marker::Unpin, 
        W : AsyncWrite + std::marker::Unpin,
        H: EndPointHandler + Sized + 'static + std::marker::Unpin,
    {
        fn new(reader: R, writer: W, handle: H) -> Self {
            Self {
                reader,
                writer,
                handle: None,
            }
        }
        fn new_with_handle(reader: R, writer: W, handle: Box<dyn EndPointHandler>) -> Self {
            Self {
                reader,
                writer,
                handle: Some(handle),
            }
        }
        fn handle(&mut self, handle: Box<dyn EndPointHandler>) {
            self.handle = Some(handle);
        }
    }

    use std::pin::Pin;
    use core::task::Context;
    use core::task::Poll;
    use tokio::io::AsyncWrite;
    use tokio::io::AsyncRead;
    use std::io::Error;
    impl<R,W, H> AsyncWrite for EndPoint<R, W, H>
    where R: AsyncRead + std::marker::Unpin, 
        W : AsyncWrite + std::marker::Unpin,
        H: EndPointHandler + Sized + 'static + std::marker::Unpin,
    {
        fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize, Error>> {
            Pin::new(&mut Pin::into_inner(self).writer).poll_write(cx, buf)
        }
        fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Error>> {
            Pin::new(&mut Pin::into_inner(self).writer).poll_flush(cx)
        }
        fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Error>>{
            Pin::new(&mut Pin::into_inner(self).writer).poll_shutdown(cx)
        }
    }

    /*
    struct Client<E> {
        endpoint: E,
    }
    impl tokio::io::AsyncWrite for Client {
    }
    */

    

    use tokio::net::TcpStream;
    use tokio::io::AsyncWriteExt;
    #[tokio::test(flavor = "multi_thread")]
    //#[ignore] // need nc -kl 3467
    async fn endpoint() -> Result<(), Box<dyn std::error::Error>>{
        /* TODO: 
        //new server on 3467, get & print value 
        tokio::spawn( async { 
            SinglePrintServer::new(3467);
        });*/

        let tcp = TcpStream::connect("127.0.0.1:3467").await?;
        let (r, w) = tcp.into_split();
        let mut ep = EndPoint::new(r, w, MyHandle{});
        let count = ep.write(&b"hello\n"[..]).await?;
        assert_eq!(count, 6);

        assert_eq!((), ep.flush().await?);
        assert_eq!((), ep.shutdown().await?);
        Ok(())
    }

    //TODO: 
    struct MyHandle {
    }
    impl EndPointHandler for MyHandle {
        fn connected(&self, e: &dyn std::error::Error) {
            println!("connected");
        }

        fn disconnected(&self, e: &dyn std::error::Error){
            println!("disconnected");
        }

        fn buf_read(&self, buf: &mut dyn bytes::Buf) {
            println!("buf_read");
        }
    }

    #[tokio::test(flavor = "multi_thread")]
    async fn endpoint_handle() -> Result<(), Box<dyn std::error::Error>> {
        let tcp = TcpStream::connect("127.0.0.1:3467").await?;
        let (r, w) = tcp.into_split();
        let mut ep = EndPoint::new_with_handle(r, w, Box::new(MyHandle{}));
        Ok(())
    }
}*/
